﻿using Grasshopper.Kernel;
using Rhino.Display;
using Rhino.DocObjects;
using Rhino.Geometry;
using System.Collections.Generic;
using System.Drawing;

namespace AiMoInGH.ScriptInstance.Preview
{
    class Previewer
    {

        public BoundingBox ClippingBox = BoundingBox.Empty;
        public void Clear()
        {
            previewObjectsMeshes.Clear();
            previewObjectsWires.Clear();
            ClippingBox = BoundingBox.Empty;
        }

        public static Color DefaultColor = Color.FromArgb(150, 2, 45, 80);

        readonly List<PreviewObject> previewObjectsMeshes = new List<PreviewObject>();
        readonly List<PreviewObject> previewObjectsWires = new List<PreviewObject>();

        public bool IsEmpty => previewObjectsMeshes.Count + previewObjectsWires.Count == 0;
        public void DrawViewportMeshes(IGH_PreviewArgs e)
        {
            foreach (PreviewObject previewObject in previewObjectsMeshes)
            {
                try
                {
                    if (previewObject != null && previewObject.Enable)
                    {
                        previewObject.Draw(e.Display);
                    }
                }
                catch
                {
                }
            }
        }
        public void DrawViewportWires(IGH_PreviewArgs e)
        {
            foreach (PreviewObject previewObject in previewObjectsWires)
            {
                try
                {
                    if (previewObject != null && previewObject.Enable)
                    {
                        previewObject.Draw(e.Display);
                    }
                }
                catch
                {
                }
            }
        }

        void AddWireObject(PreviewObject obj)
        {
            previewObjectsWires.Add(obj);
            ClippingBox.Union(obj.ClippingBox);
        }
        void AddMeshObject(PreviewObject obj)
        {
            previewObjectsMeshes.Add(obj);
            ClippingBox.Union(obj.ClippingBox);
        }
        public void Preview(Vector3d vector3d, Point3d from, Color color)
        {
            if (from.IsValid && vector3d.IsValid && !vector3d.IsZero)
            {
                AddWireObject(new PreviewVector(vector3d, from, color));
            }
        }
        public void Preview(object geo, Color color)
        {
            switch (geo)
            {
                case Point3d pt:
                    if (pt.IsValid)
                    {
                        AddWireObject(new PreviewPoint(pt, color));
                    }
                    break;
                case Point3f ptf:
                    if (ptf.IsValid)
                    {
                        AddWireObject(new PreviewPoint(new Point3d(ptf), color));
                    }
                    break;
                case PointCloud cloud:
                    if (cloud.IsValid)
                    {
                        AddWireObject(new PreviewPointCloud(cloud, color));
                    }
                    break;
                case Line line:
                    if (line.IsValid)
                        AddWireObject(new PreviewStructGeos(line, color));
                    break;
                case Box box:
                    if (box.IsValid)
                        AddWireObject(new PreviewBox(box, color));
                    break;
                case BoundingBox bbox:
                    if (bbox.IsValid)
                        AddWireObject(new PreviewBox(new Box(bbox), color));
                    break;
                case Circle circle:
                    if (circle.IsValid)
                        AddWireObject(new PreviewCircle(circle, color));
                    break;
                case Arc arc:
                    if (arc.IsValid)
                        AddWireObject(new PreviewArc(arc, color));
                    break;
                case Ellipse ellipse:
                    if (ellipse.IsValid)
                        AddWireObject(new PreviewCurve(ellipse.ToNurbsCurve(), color));
                    break;
                case Cone cone:
                    if (cone.IsValid)
                        AddWireObject(new PreviewCone(cone, color));
                    break;
                case Rectangle3d rectangle:
                    if (rectangle.IsValid)
                        AddWireObject(new DrawPolyline(rectangle.ToPolyline(), color));
                    break;
                case Polyline polyline:
                    if (polyline.IsValid && polyline.Count > 1)
                        AddWireObject(new DrawPolyline(polyline, color));
                    break;
                case Cylinder cylinder:
                    if (cylinder.IsValid)
                        AddWireObject(new DrawCylinder(cylinder, color));
                    break;
                case Plane plane:
                    if (plane.IsValid)
                        AddWireObject(new PreviewPlane(plane, color));
                    break;
                case Sphere sphere:
                    if (sphere.IsValid)
                        AddWireObject(new DrawSphere(sphere, color));
                    break;
                case AnnotationBase annotationBase:
                    AddWireObject(new PreviewAnnotationBase(annotationBase, color));
                    break;
                case Hatch hatch:
                    AddWireObject(new PreviewHatch(hatch, color));
                    break;
                case TextDot textDot:
                    AddWireObject(new PreviewTextDot(textDot, color));
                    break;

                case Curve crv:
                    AddWireObject(new PreviewCurve(crv, color));
                    break;
                case Text3d text3D:
                    AddWireObject(new PreviewText3d(text3D, color));
                    break;
                case GeometryBase geometry:
                    AddMeshObject(new PreviewGeometryBase(geometry, color));
                    break;
                case RhinoObject rhinoObject:
                    AddMeshObject(new PreviewRhinoObject(rhinoObject, color));

                    break;
            }
        }


    }
}
